package com.fruit.account.service.commission;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSONObject;
import com.fruit.account.common.CommMsgUtil;
import com.fruit.account.service.excommission.CommBackLogServiceImpl;
import com.fruit.mapper.account.balance.BalanceDetailMapper;
import com.fruit.mapper.account.commission.CommissionDetailMapper;
import com.fruit.mapper.account.rebaterule.RebateRuleMapper;
import com.fruit.mapper.account.transaction.TransactionFlowPoMapper;
import com.fruit.mapper.account.user.UserAccountMapper;
import com.fruit.pojo.account.balance.BalanceDetail;
import com.fruit.pojo.account.commission.CommissionDetail;
import com.fruit.pojo.account.excommission.ExceptionCommission;
import com.fruit.pojo.account.rebaterule.RebateRule;
import com.fruit.pojo.account.transaction.TransactionFlowPo;
import com.fruit.pojo.account.user.UserAccount;
import com.fruit.pojo.push.Message;
import com.fruit.pojo.user.UserInfo;
import com.fruit.pojo.user.sysmsg.SysMessage;
import com.fruit.sdk.account.commission.RebateService;
import com.fruit.service.push.AppPushService;
import com.fruit.service.sysmsg.SysMessageService;
import com.fruit.service.user.UserManager;
import com.fruit.util.CustomUtil;
import com.fruit.util.DateUtil;
import com.fruit.util.Exceptions;
import com.fruit.util.ResultInfo;
import com.fruit.util.ResultUtil;

/**
 * 返利业务相关Service（当前->上上->上）
 *
 * @author Administrator
 * @version 2018.01.08 10:16
 */
@Service("rebateService")
public class RebateServiceImpl implements RebateService {
    private Logger logger = LoggerFactory.getLogger(RebateServiceImpl.class);
    @Autowired
    private RebateRuleMapper rebateRuleMapper;
    @Autowired
    private UserManager userService;
    @Autowired
    private TransactionFlowPoMapper transactionFlowPoMapper;
    @Autowired
    private CommissionDetailMapper commissionDetailMapper;
    @Autowired
    private BalanceDetailMapper balanceDetailMapper;
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private SysMessageService sysMessageService;
    //	@Autowired
//	private SmsCodeManager smsCodeService;
    @Autowired
    private CommBackLogServiceImpl commBackLogServiceImpl;
    @Value("${h5_domain}")  
    private String h5Domain;

    @Autowired
    private AppPushService appPushService;

    @Override
    public Map<String, Object> insertRebate(String tradeId, Integer userId, BigDecimal money) {
        logger.info("[" + tradeId + "]---【返利处理】---【开始params】---userId=" + userId + ";money=" + money);
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            if (userId == null) {
                result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "传入参数用户id不能为空!"));
                return result;
            }
            if (money == null || money.doubleValue() <= 0) {
                result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "传入参数支付金额必须大于零!"));
                return result;
            }
            if (StringUtils.isEmpty(tradeId)) {
                result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "日志流水号不能为空!"));
                return result;
            }
            RebateRule rRule = new RebateRule();
            rRule.setStartTime(DateUtil.getTime());
            rRule.setEndTime(DateUtil.getTime());
            rRule.setState("01"); // 已启用
            rRule.setRebateType("00"); // 默认返利类型
            RebateRule recRule = rebateRuleMapper.selectByCondition(rRule); // 1、获取返利规则
            if (recRule == null) { // 规则不存在
                logger.info("[" + tradeId + "]---【返利处理】---【未匹配到返利业务规则】-----");
                result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "rule_error", "未匹配到返利业务规则"));
                return result;
            }
            logger.info("[" + tradeId + "]---【返利处理】---【规则参数】-----" + recRule.toString());
            if (recRule.getOneLevelRebate() == null) { // 一级返利点数 如果获取不到，则不执行佣金返利功能
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rule_error",
                        "获取一级返利规则点数异常！", "", "01"));
                return result;
            }
            if (recRule.getTwoLevelRebate() == null) { // 二级返利点数如果获取不到，则不执行佣金返利功能
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rule_error",
                        "获取二级返利规则点数异常！", "", "01"));
                return result;
            }
            Map<String, Object> userMap = null; // 2、获取用户上级和上上级 调用户中心的服务
            UserInfo parentOne = null; // 一级用户对象
            UserInfo parentTow = null; // 二级用户对象
            try {
                logger.info("[" + tradeId + "]---【返利处理】---【获取用户上级和上上级】-----");
                userMap = userService.getUserParent(userId);
                if (userMap == null) {
                    result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "user_error",
                            "获取到用户上级失败", "", "01"));
                    return result;
                }
                ResultInfo userRi = (ResultInfo) userMap.get("result");
                if (ResultInfo.ERROR.equals(userRi.getState())) {
                    result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "user_error",
                            "获取用户上级异常！", "", "01"));
                    return result;
                }
                parentOne = (UserInfo) userMap.get("parentOne");
                parentTow = (UserInfo) userMap.get("parentTow");
                if (parentTow == null) { //不存在消费的上上级 则不执行返利业务
                    result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "user_error",
                            "未匹配到当前用户的上上级（已消费）用户"));
                    return result;
                }
                logger.info("[" + tradeId + "]---【返利处理】---【获取用户上级和上上级】-----" + userMap.toString());
            } catch (Exception e) {
                logger.error("[" + tradeId + "]---【返利处理】---【获取用户上级和上上级异常】-----" + Exceptions.getStackTraceAsString(e));
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "user_exception",
                        "获取用户上级异常！", "", "01"));
                return result;
            }
            //站内消息
            List<SysMessage> msgList = new ArrayList<SysMessage>();
            //push消息
            List<PushMsg> pushList = new ArrayList<PushMsg>();

            // 一级返利点数等于支付金额乘以一级返利点数
            BigDecimal oneBackMoney = money.multiply(new BigDecimal(recRule.getOneLevelRebate())
                    .divide(new BigDecimal(100), 3, BigDecimal.ROUND_HALF_DOWN));
            // 1、生成一级返利
            result = insertRebate(recRule.getOneLevelRebate(), "01", parentTow, userId, oneBackMoney, userId);
            ResultInfo oneResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(oneResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rebate_error1",
                        "生成一级返利业务异常！", "", "01"));
                return result;
            }
            //站内信
            SysMessage oneMsg = CommMsgUtil.getMsgForComm(h5Domain, parentTow.getId(), oneBackMoney);
            msgList.add(oneMsg);
            //push消息
            PushMsg onPsg = new PushMsg();
            onPsg.setMsg(CommMsgUtil.getPushMsgForComm(h5Domain, oneBackMoney));
            onPsg.setUserId(parentTow.getId());
            pushList.add(onPsg);

            //存在一级用户，则执行二级返利
            if (parentOne != null) {
                // 二级返利点数等于 支付金额乘以一级返利点数再乘以二级返利点数
                BigDecimal twoBackMoney = oneBackMoney.multiply(new BigDecimal(recRule.getTwoLevelRebate()).divide
                        (new BigDecimal(100), 3, BigDecimal.ROUND_HALF_DOWN));
                // 2、生成二级返利
                result = insertTwoRebate(recRule.getTwoLevelRebate(), "02", parentOne, parentTow.getId(),
                        twoBackMoney, userId);
                ResultInfo twoResult = (ResultInfo) result.get("result");
                if (ResultInfo.ERROR.equals(twoResult.getState())) {
                    result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rebate_error2",
                            "生成二级返利业务异常！", "", "01"));
                    return result;
                }
                SysMessage twoMsg = CommMsgUtil.getMsgForComm(h5Domain, parentOne.getId(), twoBackMoney);
                msgList.add(twoMsg);
                //push消息
                PushMsg towPsg = new PushMsg();
                towPsg.setMsg(CommMsgUtil.getPushMsgForComm(h5Domain, twoBackMoney));
                towPsg.setUserId(parentOne.getId());
                pushList.add(towPsg);
            }
            // 3、发送站内信
            sendMsg(msgList);
            // 4、push消息
            pushMsg(pushList);

            result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "rebate_success", "返利业务操作成功"));
            return result;
        } catch (Exception e) {
            logger.error("[" + tradeId + "]---【返利处理】---【异常】-----" + Exceptions.getStackTraceAsString(e));
            result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "rebate_exception",
                    "返利业务处理异常！", "", "01"));
            return result;
        } finally {
            ResultInfo ri = (ResultInfo) result.get("result");
            if (ResultInfo.ROLLBACK.equals(ri.getIsRollBack())) {
                logger.info("[" + tradeId + "]---【返利处理】---【异常事务回滚】---{}---{}", ri.getMessage(), ri.getCode());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
            if (ResultInfo.ERROR.equals(ri.getState())) { // 设置异常记录信息
                logger.info("[" + tradeId + "]---【返利处理】---【日志记录】---{}---{}", ri.getMessage(), ri.getCode());
                ExceptionCommission exc = new ExceptionCommission();
                exc.setTradeId(tradeId);
                exc.setUserId(userId);
                exc.setServiceName("RebateServiceImpl");
                JSONObject paJson = new JSONObject();
                paJson.put("tradeId", tradeId);
                paJson.put("userId", userId);
                paJson.put("money", money);
                exc.setInputParams(paJson.toString());
                exc.setQueryTime(DateUtil.getTime());
                exc.setErrorCode(ri.getCode());
                exc.setErrorMessage(ri.getMessage());
                saveErrLog(exc);
            }
            logger.info("[" + tradeId + "]---【返利处理】---【结束】-----");
        }
    }

    /**
     * 返利业务处理
     *
     * @param levelRebate 返利点数
     * @param level       返利等级 01 一级；02二级
     * @param user        返利用户
     * @param pUserId     返利提供者用户id
     * @param money       返利金额
     * @param userId      消费用户id
     * @return Map<String, Object>
     */
    public Map<String, Object> insertRebate(Long levelRebate, String level, UserInfo user, Integer pUserId,
                                            BigDecimal money, Integer userId) {
        Map<String, Object> result = new HashMap<String, Object>();
        logger.info("【生成一级返利业务数据】---【开始】---");
        try {
            // 1、产生交易订单
            List<TransactionFlowPo> tflist = new ArrayList<TransactionFlowPo>(); //构建返利交易订单
            result = saveTransactionFlow(tflist, user, money, "01");
            ResultInfo tranResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(tranResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_error",
                        "生成交易订单异常！", "", "01"));
                return result;
            }
            // 2、产生返利记录
            result = insertCommission(tflist, levelRebate, level, pUserId, userId, "01");
            ResultInfo commResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(commResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, commResult.getCode(),
                        "生成返利记录异常！", "", "01"));
                return result;
            }
            // 3、产生返利用户的余额明细 并且 修改一级返利的用户账户余额
            result = updateAccountAndAddtBalance(tflist, "01");
            ResultInfo baResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(baResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, baResult.getCode(),
                        "生成账户余额明细异常！", "", "01"));
                return result;
            }

            result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "insertFirst_success", "返利业务操作成功"));
            logger.info("【生成返利业务数据】---【结束】-----");
            return result;
        } catch (Exception e) {
            logger.error("【生成返利业务数据】---【异常】-----" + Exceptions.getStackTraceAsString(e));
            result.put("result",
                    (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "insertFirst_exception", "生成返利业务数据异常！", "",
                            "01"));
            return result;
        }

    }

    /**
     * 产生二级返利
     *
     * @param levelRebate 返利点数
     * @param level       返利等级 01 一级；02二级
     * @param user        返利用户
     * @param pUserId     返利提供者用户id
     * @param money       返利金额
     * @param userId      消费用户id
     * @return Map<String, Object>
     */
    public Map<String, Object> insertTwoRebate(Long levelRebate, String level, UserInfo user, Integer pUserId,
                                               BigDecimal money, Integer userId) { // 二级返利 一级用户
        Map<String, Object> result = new HashMap<String, Object>();
        logger.info("【生成二级返利业务数据】---【开始】---");
        try {
            //========================================二级返利一级扣款业务处理=========================================
            // 1、产生一级交易订单（扣款）
            // 2、产生一级交易订单（扣款）
            // 3、产生一级返利用户的余额明细 并且 修改一级返利的用户账户余额（扣款）
            // 4、消息通知

            // 1、产生一级交易订单 （扣款）
            List<TransactionFlowPo> tflist = new ArrayList<TransactionFlowPo>(); //构建返利交易订单
            UserInfo kouUser = new UserInfo();
            kouUser.setId(pUserId);
            result = saveTransactionFlow(tflist, kouUser, money, "02"); // 一级用户二级返利
            ResultInfo tranResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(tranResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_error",
                        "生成一级扣款交易订单异常！", "", "01"));
                return result;
            }
            // 2、产生返利记录 （扣款）
            result = insertCommission(tflist, levelRebate, level, user.getId(), userId, "02");
            ResultInfo commResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(commResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, commResult.getCode(),
                        "生成一级扣款返利记录异常！", "", "01"));
                return result;
            }
            // 3、产生一级返利用户的余额明细 并且 修改一级返利的用户账户余额
            result = updateAccountAndAddtBalance(tflist, "00");
            ResultInfo baResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(baResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, baResult.getCode(),
                        "生成一级账户扣款余额明细异常！", "", "01"));
                return result;
            }

            //========================================二级返利业务处理=========================================
            // 1、产生二级交易订单
            // 2、产生二级返利记录
            // 3、产生级二返利用户的余额明细（加款） 并且 修改二级返利的用户账户余额（加款）

            result = insertRebate(levelRebate, level, user, pUserId, money, userId);
            ResultInfo twoResult = (ResultInfo) result.get("result");
            if (ResultInfo.ERROR.equals(twoResult.getState())) {
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, twoResult.getCode(),
                        "生成一级账户扣款余额明细异常！", "", "01"));
                return result;
            }

            result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "insertTwo_success", "二级返利业务操作成功"));
            logger.info("【生成二级返利业务数据】---【结束】-----");
            return result;
        } catch (Exception e) {
            logger.error("【生成二级返利业务数据】---【异常】-----" + Exceptions.getStackTraceAsString(e));
            result.put("result",
                    (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "insertTwo_exception", "二级生成返利业务数据异常！", "",
                            "01"));
            return result;
        }

    }

    /**
     * 保存交易订单
     *
     * @param tflist 交易订单集合
     * @param user   用户
     * @param money  支付金额
     * @param state  01 进   02出
     * @return 保存结果
     */
    public Map<String, Object> saveTransactionFlow(List<TransactionFlowPo> tflist, UserInfo user, BigDecimal money,
                                                   String state) {
        Map<String, Object> result = new HashMap<String, Object>();
        logger.info("【构建返利交易订单】---【开始】---");
        try {
            if (user != null) { //一级用户二级返利
                logger.info("【构建返利交易订单】---【当前用户id】-----{}", user.getId());
                // 构建一级返利交易订单
                TransactionFlowPo tFlow = new TransactionFlowPo();
                tFlow.setUserId(user.getId()); // 当前用户id
                tFlow.setTotalPrice(money.setScale(2, BigDecimal.ROUND_HALF_DOWN)); // 设置金额
                tFlow.setPayPrice(money.setScale(2, BigDecimal.ROUND_HALF_DOWN)); // 设置金额
                tFlow.setPriceState(state); // 进
                if ("02".equals(state)) {
                    tFlow.setRemark("推荐费用支出");
                    tFlow.setType("04"); // 返利
                } else {
                    tFlow.setRemark("环保卫士奖励");
                    tFlow.setType("02"); // 返利
                }
                tFlow.setState("01"); // 已支付
                tFlow.setCreateTime(DateUtil.getTime());
                tFlow.setFinishTime(DateUtil.getTime());
                tFlow.setVersion(0);
                tflist.add(tFlow);
            }
            if (tflist.size() <= 0) {
                logger.info("【构建返利交易订单】---【当前用户不存在上级】-----");
                result.put("result",
                        (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_error", "生成返利交易订单异常！"));
                return result;
            }
            logger.info("【构建返利交易订单】---【saveparams】-----" + tflist.toString());
            // 保存返利交易订单
            transactionFlowPoMapper.insertTransactionFlows(tflist);
            for (TransactionFlowPo t : tflist) {
                // 构建交易订单编码
                t.setCode(CustomUtil.orderCode(3, t.getId(), t.getUserId()));
            }
            logger.info("【构建返利交易订单】---【updateparams】-----" + tflist.toString());
            for (TransactionFlowPo tfp : tflist) {
                int upRec = transactionFlowPoMapper.updateCode(tfp);
                if (upRec != 1) {
                    logger.info("【构建返利交易订单】---【插入交易订单编码失败！】----影响记录数：=" + upRec);
                    result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_error",
                            "生成返利交易订单异常！", "", "01"));
                    return result;
                }
            }
            logger.info("【构建返利交易订单】---【结束】-----");
            result.put("result",
                    (ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "tranflow_success", "交易订单生成成功"));
            return result;
        } catch (Exception e) {
            logger.error("【构建返利交易订单】---【生成返利交易订单异常！】-----" + Exceptions.getStackTraceAsString(e));
            result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "tranflow_exception",
                    "生成返利交易订单异常！", "", "01"));
            return result;
        }
    }

    /**
     * 生成返利记录
     *
     * @param tflist      交易账单记录
     * @param levelRebate 返利点数
     * @param level       返利等级 01 一级；02二级
     * @param pUserId     进：返利提供用户id 出：返利受益者
     * @param userId      消费用户id
     * @param priceState  01 增 02 出
     * @return 保存结果
     */
    public Map<String, Object> insertCommission(List<TransactionFlowPo> tflist, Long levelRebate, String level,
                                                Integer pUserId, Integer userId, String priceState) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            logger.info("【佣金返利记录】---【开始】---");
            List<CommissionDetail> commlist = new ArrayList<CommissionDetail>(); // 构造佣金返利记录
            for (TransactionFlowPo t : tflist) {
                // 构建返利记录
                CommissionDetail commDetail = new CommissionDetail();
                commDetail.setUserId(t.getUserId()); // 用户id
                commDetail.setMoney(t.getPayPrice()); // 返利金额
                commDetail.setRebate(levelRebate); // 返利点数
                commDetail.setFriendId(pUserId); // 返利提供者id
                commDetail.setLevel(level); // 01 一级；02二级
                commDetail.setRemark(t.getRemark());
                commDetail.setTransactionId(t.getId()); // 交易订单id
                commDetail.setCreateTime(DateUtil.getTime());
                commDetail.setConsumerId(userId); // 消费者id
                commDetail.setPriceState(priceState);
                commlist.add(commDetail);
            }
            if (commlist.size() <= 0) {
                logger.error("【佣金返利记录】---【构建返利记录异常】-----");
                result.put("result",
                        (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "commiss_error", "返利记录异常！", "", "01"));
                return result;
            }
            logger.info("【佣金返利记录】---【saveparams】-----" + commlist.toString());
            // 保存返利记录
            commissionDetailMapper.insertCommissionDetails(commlist);
            result.put("result",
                    (ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "commiss_success", "生成返利记录成功！"));
            logger.info("【佣金返利记录】---【结束】-----");
            return result;
        } catch (Exception e) {
            logger.error("【佣金返利记录】---【生成返利记录异常！】-----" + Exceptions.getStackTraceAsString(e));
            result.put("result",
                    (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "commiss_exception", "生成返利记录异常！", "", "01"));
            return result;
        }
    }

    /**
     * 修改账户余额以及新增余额明细
     *
     * @param tflist 交易账单记录
     * @param state  收益状态 01 增 00 减
     * @return 保存结果
     */
    public Map<String, Object> updateAccountAndAddtBalance(List<TransactionFlowPo> tflist, String state) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            logger.info("【修改账户余额以及新增余额明细】---【开始】-----");
            List<BalanceDetail> balancelist = new ArrayList<BalanceDetail>(); // 构建返利余额明细
            List<UserAccount> uList = new ArrayList<UserAccount>(); // 构建修改用户余额
            for (TransactionFlowPo t : tflist) {
                // 获取用户账户余额
                UserAccount userAcc = userAccountMapper.selectByUserId(t.getUserId());
                if (userAcc == null) {
                    logger.error("【修改账户余额以及新增余额明细】---【构建余额明细】---【获取用户余额异常】------");
                    result.put("result",
                            (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error", "获取用户余额异常！", "",
                                    "01"));
                    return result;
                }
                logger.info("【修改账户余额以及新增余额明细】---【构建余额明细】---【获取用户余额信息】------" + userAcc.toString());
                // 余额明细
                BalanceDetail balance = new BalanceDetail();
                balance.setUserId(t.getUserId()); // 用户id
                balance.setMoney(t.getPayPrice()); // 金额
                balance.setIncomeState(state); // 收益状态 01 增 00 减
                balance.setTransactionId(t.getId());
                if ("01".equals(state)) {
                    balance.setType("03"); // 账户奖励
                } else {
                    balance.setType("04"); //  推荐支出
                }
                balance.setRemark(t.getRemark());
                balance.setCreateTime(DateUtil.getTime());
                balance.setCurBalance(userAcc.getBalance()); // 设置用户当前余额
                balancelist.add(balance);

                // 用户账单余额
                UserAccount uAccount = new UserAccount();
                uAccount.setUserId(t.getUserId()); // 变更id
                //扣款时
                if ("00".equals(state)) {
                    //判断余额是否大于等于 扣款金额
                    if (t.getPayPrice().compareTo(userAcc.getBalance()) <= 0) {
                        //变更为负数
                        BigDecimal bala = new BigDecimal(0).subtract(t.getPayPrice());
                        uAccount.setBalance(bala); // 本次变动余额
                    } else {
                        logger.error("【修改账户余额以及新增余额明细】---【用户账户余额构建参数异常】----payPrice="
                                + t.getPayPrice().toString() + "balance=" + userAcc.getBalance().toString());
                        result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error",
                                "用户账户余额构建参数异常！", "", "01"));
                        return result;
                    }
                } else {
                    uAccount.setBalance(t.getPayPrice()); // 本次变动余额
                }

                uAccount.setVersion(userAcc.getVersion()); // 设置当前版矢量
                uList.add(uAccount);
            }
            if (uList.size() <= 0) {
                logger.error("【修改账户余额以及新增余额明细】---【用户账户余额修改构建参数异常】----");
                result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error",
                        "更新用户账户余额入参异常！", "", "01"));
                return result;
            }
            if (balancelist.size() <= 0) {
                logger.error("【修改账户余额以及新增余额明细】---【构建返利余额明细异常】-----" + balancelist.toString());
                result.put("result",
                        (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error", "构建返利余额明细异常！", "",
                                "01"));
                return result;
            }
            logger.info("【修改账户余额以及新增余额明细】---【用户账户余额saveparams】-----" + uList.toString());
            // 修改用户账户余额
            for (UserAccount ua : uList) {
                int rec = userAccountMapper.updateByUserId(ua);
                if (rec != 1) {
                    logger.error("【修改账户余额以及新增余额明细】---【更新用户账户余额失败！】----影响记录数：=" + rec);
                    logger.error("【修改账户余额以及新增余额明细】---【更新用户账户参数】----[" + ua.toString() + "]");
                    result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_error",
                            "更新用户账户余额异常！", "", "01"));
                    return result;
                }
            }
            logger.info("【修改账户余额以及新增余额明细】---【saveparams】-----" + balancelist.toString());
            // 保存余额明细
            balanceDetailMapper.insertBalanceDetails(balancelist);
            result.put("result",
                    (ResultInfo) ResultUtil.initResult(ResultInfo.SUCCESS, "accAalance_success", "修改账户余额以及新增余额明细成功！"));
            logger.info("【修改账户余额以及新增余额明细】---【结束】-----");
            return result;
        } catch (Exception e) {
            logger.error("【修改账户余额以及新增余额明细】---【异常！】-----" + Exceptions.getStackTraceAsString(e));
            result.put("result", (ResultInfo) ResultUtil.initResult(ResultInfo.ERROR, "accAalance_exception",
                    "修改账户余额以及新增余额明细异常！", "", "01"));
            return result;
        }
    }

    /**
     * 发送返利消息
     *
     * @param msglist 消息集合
     */
    public void sendMsg(List<SysMessage> msglist) {
        logger.info("【发送返利消息】---【开始】-----");
        try {
            if (msglist.size() <= 0) {
                logger.error("【发送返利消息】---【构建参数异常】----");
            }
            // 根据交易订单构建 发送消息体
            for (SysMessage msg : msglist) {
                try {
                    logger.info("【发送返利消息】---【消息】-----" + msg.toString());
                    sysMessageService.insert(msg);
                } catch (Exception e) {
                    logger.error("【发送返利消息】---【异常】-----" + Exceptions.getStackTraceAsString(e));
                    continue;
                }
            }
            logger.info("【发送返利消息】---【结束】-----");
        } catch (Exception e) {
            logger.error("【发送返利消息】---【异常】-----" + Exceptions.getStackTraceAsString(e));
        }
    }

    /**
     * push返利消息
     *
     * @param list push消息集合
     */
    public void pushMsg(List<PushMsg> list) {
        logger.info("【push信息】---【开始】-----");
        // 根据 发送消息体
        for (PushMsg params : list) {
            try {
                logger.info("【push信息】---【params】---{}---{}", params.getUserId(), params.getMsg());
                appPushService.sendToAllAlias(new String[]{"" + params.getUserId()}, params.getMsg());
            } catch (Exception e) {
                logger.error("【push信息】---【异常】-----" + Exceptions.getStackTraceAsString(e));
                continue;
            }
        }
        logger.info("【push信息】---【结束】-----");
    }

    /**
     * 保存异常日志
     *
     * @param exc 异常日志
     */
    public void saveErrLog(ExceptionCommission exc) {
        logger.info("【保存异常日志】---【开始】-----");
        try {
            if (exc != null) {
                logger.info("【保存异常日志】---【params】-----" + exc.toString());
                commBackLogServiceImpl.newCommBackLog(exc);
                logger.info("【保存异常日志】---【成功】-----");
            } else {
                logger.info("【保存异常日志】---【入参为null】-----");
            }
        } catch (Exception e) {
            logger.error("【保存异常日志】---【异常】-----" + Exceptions.getStackTraceAsString(e));
        } finally {
            logger.info("【保存异常日志】---【结束】-----");
        }

    }

    /**
     * 构建消息push对象
     *
     * @author Administrator
     */
    public class PushMsg {
        private Integer userId;
        private Message msg;

        public Integer getUserId() {
            return userId;
        }

        public void setUserId(Integer userId) {
            this.userId = userId;
        }

        public Message getMsg() {
            return msg;
        }

        public void setMsg(Message msg) {
            this.msg = msg;
        }

    }
}
